package com.esl.coordinator.command;

import java.io.IOException;
import java.util.HashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.esl.coordinator.client.connector.STiTEQSocketConnector;
import com.esl.coordinator.client.connector.SocketConnector;

public class SocketCommandReceiver implements CommandReceiver {
	static final Logger LOG = LoggerFactory
			.getLogger(SocketCommandReceiver.class);

	private static HashMap<String, SocketCommandReceiver> commandReceiverInstanceMap = new HashMap<String, SocketCommandReceiver>();

	private SocketConnector socketConnector;
	private String targetCoordinatorAddress;
	private int targetCoordinatorPort;

	private String returnCommand;

	private SocketCommandReceiver(String targetCoordinatorAddress,
			int targetCoordinatorPort) {
		// move initialization of socketConnetor to sendCommand to enable full
		// multithread
		this.socketConnector = STiTEQSocketConnector.getInstance();
		this.targetCoordinatorAddress = targetCoordinatorAddress;
		this.targetCoordinatorPort = targetCoordinatorPort;
	}

	public static SocketCommandReceiver getInstance(
			String targetCoordinatorAddress, int targetCoordinatorPort) {
		String key = targetCoordinatorAddress + ":" + targetCoordinatorPort;

		// number of receiver instances is dependent on key (<ip>:<port>)
		if (!commandReceiverInstanceMap.containsKey(key)) {
			commandReceiverInstanceMap.put(key, new SocketCommandReceiver(
					targetCoordinatorAddress, targetCoordinatorPort));
		}

		return commandReceiverInstanceMap.get(key);
	}

	@Override
	public synchronized String sendCommand(byte[] command,
			int expectedResponseBytes) throws IOException {
		String serverResponse = null;

		socketConnector.openSocket(targetCoordinatorAddress,
				targetCoordinatorPort);
		if (socketConnector.isOpen()) {
			serverResponse = socketConnector.sendMessasge(command,
					expectedResponseBytes);
			setReturnCommand(serverResponse);
			socketConnector.closeSocket();
		}

		return serverResponse;
	}

	public SocketConnector getSocketConnector() {
		return socketConnector;
	}

	public void setSocketConnector(SocketConnector socketConnector) {
		this.socketConnector = socketConnector;
	}

	public String getTargetCoordinatorAddress() {
		return targetCoordinatorAddress;
	}

	public void setTargetCoordinatorAddress(String targetCoordinatorAddress) {
		this.targetCoordinatorAddress = targetCoordinatorAddress;
	}

	public int getTargetCoordinatorPort() {
		return targetCoordinatorPort;
	}

	public void setTargetCoordinatorPort(int targetCoordinatorPort) {
		this.targetCoordinatorPort = targetCoordinatorPort;
	}

	public String getReturnCommand() {
		return returnCommand;
	}

	public void setReturnCommand(String returnCommand) {
		this.returnCommand = returnCommand;
	}

}
